/*->c.vtscr */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>



#include "h.os"
#include "h.wimp"
#include "h.bbc"


#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.replay"

#include "h.vtdef"

#include "h.vtlo"
#include "h.vtfile"
#include "h.vtprint"
#include "h.vtcon"
#include "h.vtcol"
#include "h.vtkey"
#include "h.vtwimp"
#include "h.vtchar"

#include "h.vtscr"



/***************************************************************************/
/*
 Code to handle VT screen
*/
/****************************************************************************/



void setspc(int n)   /* weird 220 thing */
{
 clearchars(ttyx,ttyy,n,VTFXNONE);
}


void insertspc(int n)  /* insert a number of spc's at cursor */
{
 int atrf=attribute(ttyy)>0;
 if(n==0 || ((width>>atrf)-ttyx)<n) return;
 scrollrow(ttyx,ttyy,(width>>atrf)-ttyx-n,n);
}

void delspc(int n)  /* delete a number of chars at cursor */
{
 int atrf=attribute(ttyy)>0;
 if(n==0 || ((width>>atrf)-ttyx)<n) return;
 scrollrow(ttyx+n,ttyy,(width>>atrf)-ttyx-n,-n);
}

void insline(int n)  /* insert n lines at cursor */
{
 if(ttyy<scltop || ttyy>sclbot) return;
 if(n>(sclbot-ttyy+1)) n=sclbot-ttyy+1;
 vtrefreshcursor();
 scrollblock(ttyy,sclbot-ttyy,-n);
}

void delline(int n) /* delete n lines at cursor */
{
 if(ttyy<scltop || ttyy>sclbot) return;
 if(n>(sclbot-ttyy+1)) n=sclbot-ttyy+1;
 scrollblock(ttyy,sclbot-ttyy,n);
}


void cursorxy(int x,int y)
{
 if(ttyy==24) y=24;
 else
 if(originmode)
 {
  if(y<scltop) y=scltop;
  else 
  if(y>sclbot) y=sclbot;
 }
 else
 {
  if(y<0)  y=0;
  else 
  if(y>23) y=23;
 }
 vtsetcursorp(x,y);
}



void cursorxyns(int x,int y)
{
 if(ttyy==24) y=24;
 else
 if(y<0)      y=0;
 else 
 if(y>23)     y=23;

 vtsetcursorp(x,y);
}


/*  cursor back no wrapping */
void cursorback(int n)
{
 int x;
 x=ttyx-n;
 if(x<0) x=0;
 vtsetcursorp(x,ttyy);
}


void code127(void)
{
 if(ignorerb) return;
 cursorback(1);
 delspc(1);
}


/*  cursor forward */
void cursorforward(int n)
{
 int x;
 x=ttyx+n;
 vtsetcursorp(x,ttyy);
}


/*  cursor down    */

void cursordown(int n)
{
 int i;
 int y;

 if(ttyy==24) return;

 if(ttyy>sclbot) i=23; 
 else            i=sclbot;
 y=ttyy+n;
 if(y>i) y=i;
 vtsetcursorp(ttyx,y);
}


/*  cursor down    */

void cursordownns(int n)
{
 int y;

 if(ttyy==24) return;

 y=ttyy+n;
 if(y>23) y=23;
 vtsetcursorp(ttyx,y);
}


/* cursor up      */

void cursorup(int n)
{
 int i;
 int y;

 if(ttyy==24) return;

 if(ttyy<scltop) i=0; 
 else            i=scltop;
 y=ttyy-n;
 if(y<i) y=i;
 vtsetcursorp(ttyx,y);
}


/* cursor up      */

void cursorupns(int n)
{
 int y;

 if(ttyy==24) return;

 y=ttyy-n;
 if(y<0) y=0;
 vtsetcursorp(ttyx,y);
}

void carriagereturn(void)
{
 vtsetcursorp(0,ttyy);
}


void returnlinefeed(void)
{
 index();
 vtsetcursorp(0,ttyy);
}


void setoriginmode(void)
{
 originmode=1;
 vtsetcursorp(0,scltop);
}

void resetoriginmode(void)
{
 originmode=0;
 vtsetcursorp(0,0);
}



void index(void)
{
 if(ttyy==24) vtclearstatusline();
 else
 if(ttyy==sclbot)
 {
  vtrefreshcursor();
  scrollblock(scltop,sclbot-scltop,1);
 }
 else 
 if(ttyy<23)      vtsetcursorp(ttyx,ttyy+1);
}


void indexn(int n)
{
 while(n--) index();
}


void reverseindex(void)
{ 
 if(ttyy==24) vtclearstatusline();
 else
 if(ttyy==scltop)
 {
  vtrefreshcursor();
  scrollblock(ttyy,sclbot-scltop,-1);
 }
 else
 if(ttyy>0)       vtsetcursorp(ttyx,ttyy-1);
}


void reverseindexn(int n)
{
 while(n--) reverseindex();
}


void reverseindexns(void)
{
 if(ttyy==0)
 {
  vtrefreshcursor();
  scrollblock(0,23,-1);
 }
 else             vtsetcursorp(ttyx,ttyy-1);
}



void ttright(void)                            /* tty cursor right */
{
 if(ttyx==79) returnlinefeed();
 else         cursorforward(1);
}


void ttleft(void)                             /* tty cursor left */
{
 if(ttyx==0)
 {
  if(ttyy==0)
  {
   vtrefreshcursor();
   scrollblock(0,23,-1);
   vtsetcursorp(0,ttyy);
  } 
  else vtsetcursorp(0,ttyy-1);
 }
 else cursorback(1);
}





void clearalltabs(void)
{
 int i;
 for(i=0;i<TTYCOLS;i++)tabs[i]=0;
 vtrefreshtabs();
}


void cleartab(void)
{
 tabs[ttyx]=0;
 vtrefreshtabs();
}


void settabs()
{
 int i;
 clearalltabs();
 for(i=8;i<TTYCOLS;i+=8) tabs[i]=1;
 vtrefreshtabs();
}


void settab(void)
{
 tabs[ttyx]=1;
 vtrefreshtabs();
}



/* tab n times */

void dotab(int n)
{
 int x=ttyx;
 int atrf=attribute(ttyy)>0;

 while(n-->0)
 {
  while(x<((width>>atrf)-1))
  {
   if(tabs[++x]) break;
  }
 }

 vtsetcursorp(x,ttyy);
}



void clearscr(int flags)
{
 int y;
 if(replayfix)
 {
  replayclscode=VTCLS;
  replayclsflag=flags;
  return;
 }

 if(ttyy==24) vtclearstatusline();
 else
 {
  scrollblock(0,23,24);

  for(y=0;y<24;y++)
  {
   setattribute(0,y);
   clearchars(0,y,width,flags);
  }
 }
}


void home(void)
{
 vtsetcursorp(0,0);
}


void clearscrhome(int flags)
{
 if(replayfix)
 {
  replayclscode=VTCLSHOME;
  replayclsflag=flags;
  return;
 }
 clearscr(flags);
 home();
}


/* used by TTNS to do simple clear screen */

void vtcls(void)
{
 clearscrhome(VTFXNONE);
}



/* leave atributes alone on these three */

void eraseeol(int flags) 
{
 int atrf=attribute(ttyy)>0;
 clearchars(ttyx,ttyy,(width>>atrf)-ttyx,flags);
}


void erasesol(int flags)
{
 clearchars(0,ttyy,ttyx+1,flags);
}


void eraseline(int flags)
{
 int atrf=attribute(ttyy)>0;
 clearchars(0,ttyy,(width>>atrf),flags);
}



/* do something about attributes ! */

void eraseeop(int flags)                
{
 int y;

 y=ttyy;

 if(ttyx==0) changeattrib(ttyy,0);
 eraseeol(flags);

 if(ttyy!=24)
  while(++y<24)
  {
   setattribute(0,y);
   clearchars(0,y,width,flags);
  }
}



/* do something about attributes ! */

void erasesop(int flags)             
{
 int y;
 int atrf=attribute(ttyy)>0;

 y=ttyy;

 if(ttyx==(width>>atrf)-1) changeattrib(ttyy,0);
 erasesol(flags);

 if(ttyy!=24)
  while(--y>-1)
  {
   setattribute(0,y);
   clearchars(0,y,width,flags);
  }
}



void screentest(void)
{
 int x;
 int y;

 if(ttyy==24) return;

 clearscr(VTFXNONE);
 for(y=0;y<24;y++)
    for(x=0;x<width;x++) writechar('E',x,y);
 vtsetcursorp(0,0);
}



void setmargins(int top,int bot)
{
 if(bot>top && top>=0 && bot<=23) 
 {
  scltop=top;
  sclbot=bot;
  if(ttyy!=24)
  {
   if(originmode) vtsetcursorp(0,scltop);
   else           vtsetcursorp(0,0);
  }
 }
}


void setattrib(int newattrib)
{
 changeattrib(ttyy,newattrib);
}



void beep(void)
{
 bbc_vdu(7);
}


void screenm(int mode)    /* 1 = reverse */
{
 if(screenmode==mode) return;
 screenmode=mode;
 setstylec();
 setsys();
 colourrefresh();
}   



void go80(void)
{
 if(width==80) clearscrhome(VTFXNONE);
 else          vtreopenwidth(80);
}


void go132(void)
{
 if(width==132) clearscrhome(VTFXNONE);
 else           vtreopenwidth(132);
}




void vtdosaveblock(vtsaveblock * vtb)
{
 int i;

 vtb->ttyx=ttyx;
 vtb->ttyy=ttyy;

 for(i=0;i<4;i++) vtb->gn[i]=vtgn[i];

 vtb->gl=vtgl;
 vtb->gr=vtgr;

 vtb->foreground=foreground;
 vtb->background=background;
 vtb->rendition=rendition;
 vtb->pend=pend;
}




void savecursor(void)
{
 vtsaved=1;
 vtdosaveblock(&vtsavecursor);
}



void vtdoloadblock(vtsaveblock * vtb)
{
 int i;

 vtsetcursor(vtb->ttyx,vtb->ttyy);

 for(i=0;i<4;i++) vtgn[i]=vtb->gn[i];

 vtgl=vtb->gl;
 vtgr=vtb->gr;
 foreground=vtb->foreground;
 background=vtb->background;
 rendition=vtb->rendition;
 if(autoprint) gorendition(vtb->rendition);
 setstylec();
 pend=vtb->pend;
}



void loadcursor(void)
{
 if(!vtsaved) return;
 vtdoloadblock(&vtsavecursor);
}


/***************************************************************************/


void printable(int byte)
{
 int atrf;

 if(!spconcode && spoolflag && (byte!=127)) myspool(byte);

 if(dcs)       dcsst(byte);
 else
 if(byte==127) code127();
 else
 {
  if(ansisys) byte|=256;
  else
  if(byte>128) 
   byte=vtcsetmap[vtgn[vtgr]].map[byte-160];
  else
  if(vtssg2)
  {
   byte=vtcsetmap[vtgn[2]].map[byte-32];
   vtssg2=0;
  }
  else
  if(vtssg3)
  {
   byte=vtcsetmap[vtgn[3]].map[byte-32];
   vtssg3=0;
  }
  else
   byte=vtcsetmap[vtgn[vtgl]].map[byte-32];

  if(autoprint) printprintable(byte);

  if(pend) returnlinefeed();

  if(insertmode) insertspc(1);

  writechar(byte,ttyx,ttyy);
  atrf=attribute(ttyy)>0;

  if(ttyx==(width>>atrf)-1)
  {
   if(wrapmode)
   {
    if(ansisys) returnlinefeed();
    else        pend=1;
   }
  }
  else vtsetcursorp(ttyx+1,ttyy);
 }
}

